package com.syp.auth.common.dbrouter;

import java.lang.reflect.Method;
import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.syp.auth.common.dbrouter.annotation.DoRoute;

public class DBRouterInterceptor {

	private static final Logger logger = LoggerFactory.getLogger(DBRouterInterceptor.class);

	@Autowired
	private DBRouter dbRouter;

	@Pointcut("@annotation(com.jd.insfront.acc.common.dbrouter.annotation.DoRoute)")
	public void aopPoint() {
	}

	@SuppressWarnings("rawtypes")
	@Before("aopPoint()")
	public Object doRoute(JoinPoint jp) throws Throwable {
		logger.info("--------------------------1-------------------------");
		long t1 = System.currentTimeMillis();
		boolean result = true;
		Method method = getMethod(jp);
		DoRoute doRoute = method.getAnnotation(DoRoute.class);
		// String routeField = doRoute.routeField();
		String dbRuleName = doRoute.dbRuleName();
		Object[] args = jp.getArgs();
		if (args != null && args.length > 0) {
			for (Object arg : args) {
				long t2 = System.currentTimeMillis();
				if (arg instanceof List && ((List) arg).size() > 0) {
					arg = ((List) arg).get(0);
				}
				String routeFieldValue = (String) method.invoke(arg);
				logger.debug("routeFieldValue{}", System.currentTimeMillis() - t2);
				if (!StringUtils.isEmpty(routeFieldValue)) {
					dbRouter.doRoute(routeFieldValue, dbRuleName);
					break;
				}
			}
		}
		logger.debug("doRouteTime{}", System.currentTimeMillis() - t1);
		logger.info("---------------------2------------------------------");
		return result;
	}

	private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
		Signature sig = jp.getSignature();
		MethodSignature msig = (MethodSignature) sig;
		return getClass(jp).getMethod(msig.getName(), msig.getParameterTypes());
	}

	private Class<? extends Object> getClass(JoinPoint jp) throws NoSuchMethodException {
		return jp.getTarget().getClass();
	}

}
